#this file defines the utility for generation of events, terrain, etc.

from TFclasses.TFTerrainTypes import *
from TFclasses.TFGeoMap import TFGeoMap
import random

class TFGenerator:
    
    H = 1.0
    
    #simply randomly generate a terrain type
    def generateRandomTerrain(self, resourceUnits):
        terrains = [
                TFForest(resourceUnits),
                TFJungle(resourceUnits),
                TFMountain(resourceUnits),
                TFDesert(),
                TFFreshwater(resourceUnits),
                TFSaltwater(),
                TFGrassland(resourceUnits),
                TFTundra(),
                TFMarsh()]
    
        return random.choice(terrains)
    
    #procedurally generate a map of the given size
    def generateGeoMap(self, size):
        locale = TFGeoMap(size)
        
        locale.setElevation(0, 0, 0)
        locale.setElevation(0, 0, size - 1)
        locale.setElevation(0, size - 1, 0)
        locale.setElevation(0, size - 1, size - 1)
        
        mid = size // 2
        
        self._squareStep(locale, mid, mid, locale.getSize())
        
        return locale
    
    def _squareStep(self, locale, x, y, size):
        if(size <= 2):
            return
        else:
            dist = size - x - 1
            left = x - dist
            right = x + dist
            top = y - dist
            bottom = y + dist
            print(str(left))
            avg = (locale.getElevation(left, top) + 
                   locale.getElevation(left, bottom) +
                   locale.getElevation(right, top) + 
                   locale.getElevation(right, bottom)) // 4
            
            locale.setElevation(avg + random.randint(-5, 5), x, y)
            
            self._diamondStep(locale, x, top, size)
            self._diamondStep(locale, left, y, size)
            self._diamondStep(locale, x, bottom, size)
            self._diamondStep(locale, right, y, size)
    
    def _diamondStep(self, locale, x, y, size):
        if(size <= 2): 
            return
        else:
            dist = size - x - 1
            left = x - dist
            right = x + dist
            top = y - dist
            bottom = y + dist
            total = 0
            
            if(left >= 0):
                total += locale.getElevation(left, y)
            if(right < size):
                total += locale.getElevation(right, y)
            if(top >= 0):
                total += locale.getElevation(x, top)
            if(bottom < size):
                total += locale.getElevation(x, bottom)
                
            avg = total // 4
            
            locale.setElevation(avg + random.randint(-5, 5), x, y)
            
            dist //= 2
            
            if(left >= 0):
                if(top >= 0):
                    self._squareStep(locale, x - dist, y - dist, size // 2 + 1)
                if(bottom < size):
                    self._squareStep(locale, x - dist, y + dist, size // 2 + 1)
            if(right < size):
                if(top >= 0):
                    self._squareStep(locale, x + dist, y - dist, size // 2 + 1)
                if(bottom < size):
                    self._squareStep(locale, x + dist, y + dist, size // 2 + 1)
        
        